package com.jd.ty.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.jd.ty.dao.FunctionDAO;
import com.jd.ty.dao.PermissionDAO;
import com.jd.ty.dao.RoleDAO;
import com.jd.ty.dao.UserDAO;
import com.jd.ty.dao.constant.QueryConstants;
import com.jd.ty.dao.util.HqlCriterions;
import com.jd.ty.pojo.Employee;
import com.jd.ty.pojo.Function;
import com.jd.ty.pojo.Permission;
import com.jd.ty.pojo.Role;
import com.jd.ty.pojo.User;
import com.jd.ty.service.exception.ErrorCode;
import com.jd.ty.service.exception.ErrorMessage;
import com.jd.ty.service.exception.ServiceException;
import com.jd.ty.util.CommonUtils;
import com.jd.ty.util.Pager;

public class RoleService {

	private RoleDAO roleDAO;
	private PermissionDAO permissionDAO;
	
	private FunctionDAO functionDAO;
	private UserDAO userDAO;

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	@SuppressWarnings("unchecked")
	public List<Role> getList(String filter) {
		List<Role> roles = (List<Role>) roleDAO.getByQuery(filter);
		initRoleList(roles);
		
		return roles;
	}

	@SuppressWarnings("unchecked")
	public List<Role> getList(String filter, String sort) {
		List<Role> roles = (List<Role>)roleDAO.getByQuery(filter, sort);
		initRoleList(roles);
		
		return roles;
	}

	@SuppressWarnings("unchecked")
	public List<Role> getList(Pager pager, String filter, String sort) {
		List<Role> roles=(List<Role>)	roleDAO.getByQuery(pager, filter, sort);
		initRoleList(roles);
		return roles;
	}
	
	private void initRoleList(List<Role> roles){
		for (Role role : roles) {
			initRole(role);
		}
	}
	
	private void initRole(Role role){
		List<Permission> pers= role.getPermissions();
		for (Permission permission : pers) {
			roleDAO.initialize(permission);
			roleDAO.initialize(permission.getFunction());
		}
	}

	public Role get(long id) {
		Role role = (Role) roleDAO.getById(id);
		initRole(role);
		return role;
	}

	public Role load(long id) {
		Role role = (Role) roleDAO.loadById(id);
		initRole(role);
		return role;
	}

	

	public void add(final Role role) throws ServiceException {
		HqlCriterions hc = new HqlCriterions();
		hc.and(QueryConstants.Role.ROLE_NAME, role.getRoleName(),
				QueryConstants.EQ);

		if (roleDAO.getCountByQuery(hc.getHqlString()) > 0) {
			String errMsg = CommonUtils.formatString(ErrorMessage.DUPLICATION_ENTITY_ROLE, 
					new String[]{role.getRoleName()});
			throw new ServiceException(ErrorCode.DUPLICATION_ENTITY, errMsg);
		}
		updatePermission2Role(role,null);
		roleDAO.saveOrUpdate(role);

	}

	public void update(final Role role) throws ServiceException {
		HqlCriterions hc = new HqlCriterions();
		hc.and(QueryConstants.Role.ROLE_NAME, role.getRoleName(),
				QueryConstants.EQ);

		hc.and(QueryConstants.Role.ROLE_ID, role.getRoleId(), QueryConstants.NE);

		if (roleDAO.getCountByQuery(hc.getHqlString()) > 0) {
			String errMsg = CommonUtils.formatString(ErrorMessage.DUPLICATION_ENTITY_ROLE, 
					new String[]{role.getRoleName()});
			throw new ServiceException(ErrorCode.DUPLICATION_ENTITY, errMsg);
		}
		Role newRole = (Role) roleDAO.loadById(role.getRoleId());
		initRole(newRole);
	
		updatePermission2Role(role,newRole.getPermissions());
		newRole.setPermissions(role.getPermissions());
		newRole.setAdmin(role.getAdmin());
		newRole.setRoleId(role.getRoleId());
		newRole.setRoleName(role.getRoleName());
		
		roleDAO.saveOrUpdate(newRole);
	}

	private void updatePermission2Role(final Role role,List<Permission> pemissions) {
		if (pemissions != null) {
			Permission[] tmpPermissions = new Permission[pemissions.size()];
			pemissions.toArray(tmpPermissions);
			for (int i = tmpPermissions.length - 1; i >= 0; i--) {
				tmpPermissions[i].unlinkRole();
				permissionDAO.delete(tmpPermissions[i]);
			}
		}
		if(!role.isAdmin()){
			Long[] ids= role.getPermissionIds();
			List<Permission> permissions=new ArrayList<Permission>();
			HqlCriterions hc = new HqlCriterions();
			for (int i = 0; i < ids.length; i++) {
				hc.or(QueryConstants.Function.FUNCTION_ID,ids[i],QueryConstants.EQ);
			}
			List<Function> functions=(List<Function>)functionDAO.getByQuery(hc.getHqlString());
			for (Function fun : functions) {
				fun.getFunctionId();
				Permission per = new Permission();
				per.setFunction(fun);
				permissions.add(per);
			}
			for (Permission per : permissions) {
				per.linkToRole(role);
			}
		}
	}

	public void delete(Long id) {
		HqlCriterions hc = new HqlCriterions();
		hc.and(QueryConstants.User.ROLE+"."+QueryConstants.Role.ROLE_ID, id,
				QueryConstants.EQ);
		List<User> users=userDAO.getByQuery(hc.getHqlString());
		for (User user : users) {
			user.setRole(null);
			userDAO.saveOrUpdate(user);
		}
		Role role = load(id);
		if (role != null) {
			roleDAO.delete(role);
		}

	}

	public List<Function> loadFunctionsByeRoleId(long id) {
		Role role = (Role) roleDAO.loadById(id);
		 List<Function> functions=new ArrayList<Function>();
		for (Permission permission : role.getPermissions()) {
			roleDAO.initialize(permission);
			roleDAO.initialize(permission.getFunction());
			functions.add(permission.getFunction());
		}
		return functions;
	}




	public PermissionDAO getPermissionDAO() {
		return permissionDAO;
	}

	public void setPermissionDAO(PermissionDAO permissionDAO) {
		this.permissionDAO = permissionDAO;
	}



	public RoleDAO getRoleDAO() {
		return roleDAO;
	}

	public void setRoleDAO(RoleDAO RoleDAO) {
		this.roleDAO = RoleDAO;
	}

	public FunctionDAO getFunctionDAO() {
		return functionDAO;
	}

	public void setFunctionDAO(FunctionDAO functionDAO) {
		this.functionDAO = functionDAO;
	}




}
